package com.evl.api.ticket.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.evl.api.ticket.service.ITicketService;
import com.evl.api.ticket.vo.OptionalSeatListRS;
import com.evl.api.ticket.vo.OptionalSeatRS;
import com.evl.api.ticket.vo.SearchTrainRS;
import com.evl.api.ticket.vo.SeatTypeRS;
import com.evl.common.constant.Const;
import com.evl.common.persistence.dao.ScheduleStationMapper;
import com.evl.common.persistence.dao.StationSeatRMapper;
import com.evl.common.persistence.dao.TicketPriceMapper;
import com.evl.common.persistence.dao.TicketRemainderMapper;
import com.evl.common.persistence.dao.TrainSeatScheduleMapper;
import com.evl.common.persistence.model.ScheduleStation;
import com.evl.common.persistence.model.TicketPrice;
import com.evl.common.persistence.model.TicketRemainder;
import com.evl.common.persistence.model.TrainSeatSchedule;
import com.evl.constant.CarriageLocationType;
import com.evl.constant.CarriageType;
import com.evl.constant.TrainSeatType;
import com.evl.core.cache.CacheKit;
import com.evl.trainSeat.service.ITrainSeatService;
import com.evl.utils.DateUtils;
import com.evl.utils.JsonUtils;
import com.google.common.reflect.TypeToken;

@Service
public class TicketServiceImpl implements ITicketService{

	@Resource
	TicketRemainderMapper ticketRemainderMapper;
	
	@Resource
    ScheduleStationMapper scheduleStationMapper; 
	
	@Resource
    TicketPriceMapper ticketPriceMapper;
	
	@Resource
	TrainSeatScheduleMapper trainSeatScheduleMapper;
	
	@Resource
	StationSeatRMapper stationSeatRMapper;
	
	@Resource
	ITrainSeatService trainSeatService;

	@Override
	public List<ScheduleStation> selectScheduleStations(int staId) {
		
		//从缓存取
		List<ScheduleStation> sStaionList = CacheKit.get(Const.START_TO_END_STATIONLINE, staId);
		
		//获取当前车次的站点列表
		if(sStaionList == null){
			sStaionList = scheduleStationMapper.selectScheduleStations(staId);
			//存入缓存
			CacheKit.put(Const.START_TO_END_STATIONLINE, staId, sStaionList);
		}
		
		return sStaionList;
	}

	@Override
	public SearchTrainRS transformSearchTrainRS(TicketRemainder tr, boolean isDetail) {
		
		SearchTrainRS srs = new SearchTrainRS();
    	srs.setDepartureName(tr.getDeparture());
    	srs.setArriveName(tr.getArrive());
    	srs.setDepartureTime(DateUtils.getSpecifyDate(tr.getStartTime(), DateUtils.FORMAT_YYYY_MM_DD_HH_MI_SS));
    	srs.setArriveTime(DateUtils.getSpecifyDate(tr.getArrTime(), DateUtils.FORMAT_YYYY_MM_DD_HH_MI_SS));
    	srs.setDepartureTimeStr(DateUtils.getSpecifyDate(tr.getStartTime(), DateUtils.FORMAT_HH_MM));
    	srs.setArriveTimeStr(DateUtils.getSpecifyDate(tr.getArrTime(), DateUtils.FORMAT_HH_MM));
    	srs.setStaId(String.valueOf(tr.getStaId()));
		srs.setTrainNo(tr.getTrainNo());
		srs.setCostTime(DateUtils.getDifferenceTime(tr.getStartTime(), tr.getArrTime()));
		
		Map<Integer,Integer> map = (Map<Integer, Integer>) JsonUtils.fromJson(tr.getSeatDetail(), new TypeToken<Map<Integer, Integer>>() {}.getType());
		
		//获取出发站至到达站的的站点线路信息
		List<ScheduleStation> scheduleStationList = trainSeatService.getStationLine(String.valueOf(tr.getStaId()), tr.getDeparture(), tr.getArrive());
		
		List<SeatTypeRS> seatList = selectTickeTypePrice(map,scheduleStationList);
		srs.setSeats(seatList);
		
		if(isDetail){//如果是详情页就获取座位分布集合

			List<OptionalSeatRS> optionalSeats= getOptionalSeats(tr,scheduleStationList);
			srs.setOptionalSeats(optionalSeats);
		}
		
		
    	return srs;
	}
	
	/**
	 * 获取所选车站席别票价(默认成人票价)
	 * @param map
	 * @param scheduleStationList
	 * @return
	 */
	private List<SeatTypeRS> selectTickeTypePrice(Map<Integer, Integer> map, List<ScheduleStation> scheduleStationList) {
		
		List<SeatTypeRS> seatList =new ArrayList<SeatTypeRS>();
		
		//获取所选车站的所有席别价格(需求确认：全程一个价格)
		List<TicketPrice> ticketPriceList = ticketPriceMapper.selectTickeTypePrices(scheduleStationList);
		
		//遍历席别
		for(Map.Entry<Integer, Integer> entry : map.entrySet()){
			SeatTypeRS seatRS = new SeatTypeRS();
			seatRS.setSeatTypeId(entry.getKey());
			seatRS.setSeatTypeName(TrainSeatType.valueOf(entry.getKey()));
			seatRS.setSeatNum(entry.getValue());
			
			for(TicketPrice ticketPrice : ticketPriceList){
				if(ticketPrice.getSeatType().equals(String.valueOf(entry.getKey()))){
					seatRS.setPrice(seatRS.getPrice()==null ? ticketPrice.getPrice() : seatRS.getPrice()+ticketPrice.getPrice());
				}
			}
			
			seatList.add(seatRS);
		}
		
		return seatList;
	}
	
	/**
	 * 获取座位分布集合
	 * @param tr
	 * @param scheduleStationList
	 * @return
	 */
	public List<OptionalSeatRS> getOptionalSeats(TicketRemainder tr, List<ScheduleStation> scheduleStationList){
		
		List<OptionalSeatRS> optionalSeats = new ArrayList<OptionalSeatRS>();
		
		//查询车次所有的座位
		List<TrainSeatSchedule> seatScheduleList = trainSeatScheduleMapper.selectTrainSeatSchedules(tr.getStaId(),null,null,null);
		
		//TODO 获取对应站点的座位列表（可选）存入map集合 --可以抽取公共方法
		Map<Integer,List<Integer>> map = new HashMap<Integer, List<Integer>>();
		for (ScheduleStation ss : scheduleStationList){
			//TODO 一次性查询，在后台解析
			List<Integer> seatIdList = stationSeatRMapper.selectStationSeatIds(ss.getId());
			map.put(ss.getId(), seatIdList);
		}
		
		//获取每个站点的座位id列表（可选）的交集
		List<Integer> intersectionList = new ArrayList<Integer>();
		for(Map.Entry<Integer, List<Integer>> entry : map.entrySet()){
			if(intersectionList.size() == 0){//如何集合为空，赋值
				intersectionList = entry.getValue();
			} else{//取各个站点的集合交集
				intersectionList.retainAll(entry.getValue());
			}
		}
		
		//----------封装前端车厢座位集合
		SortedMap<String,OptionalSeatRS> ocmap= new TreeMap<String,OptionalSeatRS>();
		//抽取车厢存入map
		for(TrainSeatSchedule tss : seatScheduleList){
			
			OptionalSeatRS optionalSeatRS = new OptionalSeatRS();
			optionalSeatRS.setCoachNo(tss.getCarriageNo());
			optionalSeatRS.setCoachType(CarriageType.valueStrOf(tss.getSeatType()));//车厢类型（硬卧，软卧）
			
			ocmap.put(tss.getCarriageNo(), optionalSeatRS);
		}
		
		//将车厢存入list
		for(Map.Entry<String,OptionalSeatRS> entry :ocmap.entrySet()){
			optionalSeats.add(entry.getValue());
		}
		
		//抽取座位号存入 map(01\02\03...)
		for(OptionalSeatRS osRS :optionalSeats){
			
			//座位号与位置map
			SortedMap<String,List<OptionalSeatListRS>> osMap = new TreeMap<String, List<OptionalSeatListRS>>();
			
			for(TrainSeatSchedule tss : seatScheduleList){
				
				String seatNum = tss.getSeatNo().substring(1);
				
				//判断座位号所在的车厢是否一致
				if(tss.getCarriageNo().equals(osRS.getCoachNo())){

					osMap.put(seatNum, null);
				}
			}
			
			
			int rows= 0;//座位排数
			List<Map<String,Object>> rowList=new ArrayList<Map<String,Object>>();
			
			for(Map.Entry<String,List<OptionalSeatListRS>> entry : osMap.entrySet()){
				SortedMap<String,Object> rowmap = new TreeMap<String, Object>();
				
				List<OptionalSeatListRS> list = new ArrayList<OptionalSeatListRS>();
				for(TrainSeatSchedule tss : seatScheduleList){
					
					String seatNum = tss.getSeatNo().substring(1);
					
					//判断车厢号和位置是否一致
					if(tss.getCarriageNo().equals(osRS.getCoachNo()) && seatNum.equals(entry.getKey())){
						
						OptionalSeatListRS oslRs = new OptionalSeatListRS();
						oslRs.setSeatId(tss.getId());
						oslRs.setSeatNo(CarriageLocationType.valueStrOf(tss.getSeatNo().substring(0,1)));
						oslRs.setSeatStatus(intersectionList.contains(tss.getId()) == true ? Const.SEAT_CHOOSABLE : Const.SEAT_LOCKED);
						oslRs.setSeatType(tss.getSeatType());
						list.add(oslRs);
						//将list存入map的value
						entry.setValue(list);
					}
				}
				
				//座位按上中下排序
				Collections.sort(entry.getValue(), new Comparator<OptionalSeatListRS>(){
					@Override
					public int compare(OptionalSeatListRS o1,
							OptionalSeatListRS o2) {
						return o1.getSeatNo().compareTo(o2.getSeatNo());  
					}
					
				});
				
				rowmap.put("rowNum", ++rows);
				rowmap.put("rowList", entry.getValue());
				rowList.add(rowmap);
			}
			
			osRS.setRows(rowList);
		}
	
		return optionalSeats;
	}
	
		
	/*public static void main(String[] args) {
		List<Map<String,Object>> ll=new ArrayList<Map<String,Object>>();
		
		Map<String,Object> map=new HashMap<String, Object>();
		map.put("no", "1");
		map.put("list", new ArrayList());
		
	}*/
}
